package com.ruicar.afs.cloud.parameter.commom.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * @description: VIN工具类
 * @author: sijun.yu
 * @date: 2020/8/6 18:19
 */
public class VinUtils {

    /**
     * 数字和英文字母对应数
     */
    private static final Map<Character, Integer> CHAR_WEIGHTS = new HashMap<Character, Integer>(){{
        put('0', 0);
        put('1', 1);
        put('2', 2);
        put('3', 3);
        put('4', 4);
        put('5', 5);
        put('6', 6);
        put('7', 7);
        put('8', 8);
        put('9', 9);
        put('A', 1);
        put('B', 2);
        put('C', 3);
        put('D', 4);
        put('E', 5);
        put('F', 6);
        put('G', 7);
        put('H', 8);
        put('J', 1);
        put('K', 2);
        put('L', 3);
        put('M', 4);
        put('N', 5);
        put('P', 7);
        put('R', 9);
        put('S', 2);
        put('T', 3);
        put('U', 4);
        put('V', 5);
        put('W', 6);
        put('X', 7);
        put('Y', 8);
        put('Z', 9);
    }};

    /**
     * 加权系数
     */
    private static final int[] POS_WEIGHTS = new int[]{8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2};

    /**
     * VIN有效性验证
     * @param vin
     * @return
     */
    public static boolean isValidVin(String vin){
        if(null == vin){
            return false;
        }else {
            int sum = 0;
            int check = 0;
            for(int i=0;i< vin.length();i++){
                char code = vin.toUpperCase().charAt(i);
                Integer charWeights = CHAR_WEIGHTS.get(code);
                if (null == charWeights){
                    return false;
                }else {
                    sum += charWeights * POS_WEIGHTS[i];
                    if(8 == i){
                        if('X' == code){
                            check = 10;
                        }else if(code>='0' && code <='9'){
                            check = Integer.valueOf(String.valueOf(code));
                        }else{
                            return false;
                        }
                    }
                }
            }
            return check == sum % 11;
        }
    }
}
